package pokerclient.view;

import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.ActionMap;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextPane;
import javax.swing.JToolBar;

import javax.swing.border.LineBorder;

import org.jdesktop.application.Action;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

import common.Card;
import common.GameState;

import pokerclient.core.ClientModel;
import pokerclient.core.Player;
import pokerclient.core.Utils;
import pokerclient.ctrl.ClientController;
import pokerclient.view.panels.ActionPanel;
import pokerclient.view.panels.CardPanel;
import pokerclient.view.panels.DealerPanel;
import pokerclient.view.panels.PotPanel;

/**
 * This code was edited or generated using CloudGarden's Jigloo
 * SWT/Swing GUI Builder, which is free for non-commercial
 * use. If Jigloo is being used commercially (ie, by a corporation,
 * company or business for any purpose whatever) then you
 * should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details.
 * Use of Jigloo implies acceptance of these licensing terms.
 * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
 * THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
 * LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
 */

public class ClientView extends SingleFrameApplication implements PropertyChangeListener {
	private JMenuBar menuBar;
	private JPanel cardPanelContainer;
	private JMenu Network;
	private JMenuItem Exit;
	private JButton startGameButton;
	private JScrollPane jScrollPane1;
	private JMenuItem hostMenuItem;
	private JMenuItem aboutMenuItem;
	private JMenu helpMenu;
	private JMenuItem connectMenuItem;
	private CardPanel cardPanel4;
	private CardPanel cardPanel3;
	private JTextPane eventsTextPane;
	private CardPanel cardPanel2;
	private CardPanel cardPanel1;
	private ActionPanel actionPanel1;
	private PotPanel potPanel1;
	private DealerPanel dealerPanel1;
	private JPanel topPanel;
	private JMenuItem startGameMenuItem;
	private JMenu gameMenu;
	private JSeparator jSeparator;
	private JButton exitButton;
	private JButton hostButton;
	private JButton connectButton;
	private JToolBar toolBar;
	private JPanel toolBarPanel;
	private JPanel contentPanel;
	private ClientController ctrl = ClientController.getInstance();
	private JDialog aboutBox;
	private boolean hosted = false;

	private CardPanel[] cardPanelField;

	private ActionMap getAppActionMap() {
		return Application.getInstance().getContext().getActionMap(this);
	}

	@Override
	protected void startup() {
		ClientModel.getInstance().addObserver(this);

		// set icon of the program
		Image icon = Toolkit.getDefaultToolkit().getImage(
				this.getMainFrame().getClass().getResource(
						"/pokerclient/view/resources/icons/poker.png"));
		this.getMainFrame().setIconImage(icon);

		{
			getMainFrame().setSize(900, 650);
		}
		{

			topPanel = new JPanel();
			BorderLayout panelLayout = new BorderLayout();
			topPanel.setLayout(panelLayout);
			topPanel.setPreferredSize(new java.awt.Dimension(800, 600));
			{
				contentPanel = new JPanel();
				GroupLayout contentPanelLayout = new GroupLayout(
						(JComponent) contentPanel);
				contentPanel.setLayout(contentPanelLayout);
				topPanel.add(contentPanel, BorderLayout.CENTER);
				contentPanel.setPreferredSize(new java.awt.Dimension(850, 450));
				contentPanel.setSize(800, 450);
				{
					dealerPanel1 = new DealerPanel();
					dealerPanel1.setBorder(new LineBorder(new java.awt.Color(0,
							0, 0), 1, false));
				}
				{
					potPanel1 = new PotPanel();
					potPanel1.setSize(300, 100);
					potPanel1.setBorder(new LineBorder(new java.awt.Color(0, 0,
							0), 1, false));
				}
				{
					actionPanel1 = new ActionPanel();
					actionPanel1.setBorder(new LineBorder(new java.awt.Color(0,
							0, 0), 1, false));
				}
				{
					jScrollPane1 = new JScrollPane();
					jScrollPane1.setName("jScrollPane1");
					{
						eventsTextPane = new JTextPane();
						jScrollPane1.setViewportView(eventsTextPane);
						eventsTextPane.setName("eventsTextPane");
						eventsTextPane.setBorder(new LineBorder(
								new java.awt.Color(0, 0, 0), 1, false));
					}
				}
				{
					cardPanelContainer = new JPanel();
					cardPanelContainer.setBorder(new LineBorder(
							new java.awt.Color(0, 0, 0), 1, false));
					{
						cardPanel1 = new CardPanel();
						cardPanelContainer.add(cardPanel1);
						cardPanel1.setPreferredSize(new java.awt.Dimension(230,
								100));
						cardPanel1.setName("cardPanel1");
					}
					{
						cardPanel2 = new CardPanel();
						cardPanelContainer.add(cardPanel2);
						cardPanel2.setPreferredSize(new java.awt.Dimension(230,
								100));
						cardPanel2.setName("cardPanel2");
					}
					{
						cardPanel3 = new CardPanel();
						cardPanelContainer.add(cardPanel3);
						cardPanel3.setPreferredSize(new java.awt.Dimension(230,
								100));
						cardPanel3.setName("cardPanel3");
					}
					{
						cardPanel4 = new CardPanel();
						cardPanelContainer.add(cardPanel4);
						cardPanel4.setPreferredSize(new java.awt.Dimension(230,
								100));
						cardPanel4.setName("cardPanel4");
					}
				}
				contentPanelLayout
						.setVerticalGroup(contentPanelLayout
								.createParallelGroup()
								.addGroup(
										contentPanelLayout
												.createSequentialGroup()
												.addComponent(
														potPanel1,
														GroupLayout.PREFERRED_SIZE,
														96,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														cardPanelContainer,
														GroupLayout.PREFERRED_SIZE,
														468,
														GroupLayout.PREFERRED_SIZE))
								.addGroup(
										contentPanelLayout
												.createSequentialGroup()
												.addComponent(
														dealerPanel1,
														GroupLayout.PREFERRED_SIZE,
														156,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														actionPanel1,
														GroupLayout.PREFERRED_SIZE,
														59,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														jScrollPane1,
														GroupLayout.PREFERRED_SIZE,
														349,
														GroupLayout.PREFERRED_SIZE)));
				contentPanelLayout
						.setHorizontalGroup(contentPanelLayout
								.createSequentialGroup()
								.addGroup(
										contentPanelLayout
												.createParallelGroup()
												.addComponent(
														dealerPanel1,
														GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE,
														608,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														actionPanel1,
														GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE,
														608,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														jScrollPane1,
														GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE,
														608,
														GroupLayout.PREFERRED_SIZE))
								.addGroup(
										contentPanelLayout
												.createParallelGroup()
												.addComponent(
														potPanel1,
														GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE,
														276,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														cardPanelContainer,
														GroupLayout.Alignment.LEADING,
														GroupLayout.PREFERRED_SIZE,
														276,
														GroupLayout.PREFERRED_SIZE)));
			}
			{
				toolBarPanel = new JPanel();
				topPanel.add(toolBarPanel, BorderLayout.NORTH);
				BorderLayout jPanel1Layout = new BorderLayout();
				toolBarPanel.setLayout(jPanel1Layout);
				{
					toolBar = new JToolBar();
					toolBarPanel.add(toolBar, BorderLayout.CENTER);
					{
						connectButton = new JButton();
						toolBar.add(connectButton);
						connectButton.setName("connectButton");
						connectButton.setFocusable(false);
						connectButton.setAction(getAppActionMap().get(
								"connectAction"));
					}
					{
						startGameButton = new JButton();
						toolBar.add(startGameButton);
						startGameButton.setName("startGameButton");
						startGameButton.setAction(getAppActionMap().get(
								"startGameAction"));
						startGameButton
								.setPreferredSize(new java.awt.Dimension(75, 21));
					}
					{
						hostButton = new JButton();
						toolBar.add(hostButton);
						hostButton.setName("hostButton");
						hostButton.setFocusable(false);
						hostButton.setAction(getAppActionMap()
								.get("hostAction"));
					}
					{
						exitButton = new JButton();
						toolBar.add(exitButton);
						exitButton.setName("exitButton");
						exitButton.setFocusable(false);
						exitButton.setAction(getAppActionMap()
								.get("exitAction"));
					}
				}
				{
					jSeparator = new JSeparator();
					toolBarPanel.add(jSeparator, BorderLayout.SOUTH);
				}
			}
		}
		menuBar = new JMenuBar();
		{
			gameMenu = new JMenu();
			menuBar.add(gameMenu);
			gameMenu.setName("gameMenu");
			{
				startGameMenuItem = new JMenuItem();
				gameMenu.add(startGameMenuItem);
				startGameMenuItem.setName("startGameMenuItem");
				startGameMenuItem.setAction(getAppActionMap().get(
						"startGameAction"));
			}
			{
				Exit = new JMenuItem();
				gameMenu.add(Exit);
				Exit.setName("Exit");
				Exit.setAction(getAppActionMap().get("exitAction"));
			}
		}
		{
			Network = new JMenu();
			menuBar.add(Network);
			Network.setName("Network");
			{
				connectMenuItem = new JMenuItem();
				Network.add(connectMenuItem);
				connectMenuItem.setName("connectMenuItem");
				connectMenuItem.setAction(getAppActionMap()
						.get("connectAction"));
			}
			{
				hostMenuItem = new JMenuItem();
				Network.add(hostMenuItem);
				hostMenuItem.setName("hostMenuItem");
				hostMenuItem.setAction(getAppActionMap().get("hostAction"));
			}
		}
		{
			helpMenu = new JMenu();
			menuBar.add(helpMenu);
			helpMenu.setName("helpMenu");
			{
				aboutMenuItem = new JMenuItem();
				helpMenu.add(aboutMenuItem);
				aboutMenuItem.setName("aboutMenuItem");
				aboutMenuItem.setAction(getAppActionMap().get("aboutAction"));
			}
		}
		getMainFrame().setJMenuBar(menuBar);
		show(topPanel);

		// For future ease of use we stick the CardPanels into a field:
		cardPanelField = new CardPanel[4];
		cardPanelField[0] = cardPanel1;
		cardPanelField[1] = cardPanel2;
		cardPanelField[2] = cardPanel3;
		cardPanelField[3] = cardPanel4;
	}

	private void addPlayerInfo(Player player, int position, boolean started) {
		if (position > -1 && position < 4) {
			cardPanelField[position].setBoxes(player, position, started);
			cardPanelField[position].setVisible(true);
		}
	}

	private void setPot(int value) {
		potPanel1.setPot(value);
	}

	@Action
	public void connectAction() {
		String host = "localhost"; // default value, also the value when you
		// host.
		String nick = JOptionPane
				.showInputDialog("Enter your nickname please:");

		if (!hosted) {
			host = JOptionPane
					.showInputDialog("Enter the desired host address:");
			if (host == null) {
				return; //user clicked cancel, return.
			}
		}

		// Make sure the user actually entered something:
		if (nick != null) {
			ctrl.connectButtonPressed(nick, host);
		} else {
			nick = "Defaultplayer";
			ctrl.connectButtonPressed(nick, host);
		}
		hosted = false;
	}

	@Action
	public void hostAction() {
		ctrl.hostButtonPressed();
		hosted = true;
		connectAction();
	}

	@Action
	public void exitAction() {
		this.getMainFrame().dispose();
	}

	@Action
	public void aboutAction() {
		if (aboutBox != null) {
			aboutBox.setVisible(true);
		} else {
			aboutBox = new AboutDialog(new JFrame());
		}
	}

	@Action
	public void startGameAction() {
		ctrl.startGameButtonPressed();
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if (evt.getPropertyName().equals("PLAYER")) {
			// The incoming value is a player:
			Player player = (Player) evt.getNewValue();
			int position = player.getPosition();
			addPlayerInfo(player, position, false);
			
		} else if (evt.getPropertyName().equals("MESSAGE_TO_PLAYER")) {
			// The incoming value is a message to the player:
			String incomingText = (String) evt.getNewValue();
			String previousText = eventsTextPane.getText();
			eventsTextPane.setText(incomingText + "\n" + previousText);
			
		} else if (evt.getPropertyName().equals("COMMUNITY_CARDS")) {
			// We have been given a list of community cards. We should send this
			// list to the dealer panel!
			Card[] communityCards = (Card[]) evt.getNewValue();
			dealerPanel1.showFlop(communityCards);
			
		} else if (evt.getPropertyName().equals("ENABLED_ACTIONS")) {
			// We have an array of booleans on our hands! This represents a list
			// of what actions the player should be able to perform at this
			// time. We set buttons accordingly!
			boolean[] enabledActions = (boolean[]) evt.getNewValue();

			connectButton.setEnabled(enabledActions[0]);
			connectMenuItem.setEnabled(enabledActions[0]);
			startGameButton.setEnabled(enabledActions[1]);
			startGameMenuItem.setEnabled(enabledActions[1]);
			hostButton.setEnabled(enabledActions[2]);
			hostMenuItem.setEnabled(enabledActions[2]);

			actionPanel1.enableGameActionButtons(enabledActions);
			
		} else if (evt.getPropertyName().equals("GAME_STATE")) {
			// The really long one:
			
			GameState gameState = (GameState) evt.getNewValue();

			int position = gameState.getPosition();

			Player[] playerArray = Utils.playerListConversion(gameState
					.getPlayerList(), position);
			// Instantiate the playerCounter here. We'll use it later. It's set
			// to 1 due to the fact that the array we're going to be going
			// through already lacks the position of the main player.
			int playerCounter = 1;

			for (int index = 0; index < 4; index++) {
				Player player = playerArray[index];
				if (player != null) {
					playerCounter++;

					addPlayerInfo(player, index, gameState.hasStarted());

					// Set the colour of other player's card panels:
					cardPanelField[index].setYellowBackground(gameState
							.hasStarted()
							&& index == gameState.getTurnCounter());
				}
			}

			// Set the colour of the main player's card panel:
			cardPanelField[gameState.getPosition()]
					.setYellowBackground(gameState.hasStarted()
							&& position == gameState.getTurnCounter());

			setPot(gameState.getPot());
		}
		
	}
}
